# -*- coding: utf-8 -*-
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
#作者：cacho_37967865
#博客：https://blog.csdn.net/sinat_37967865
#文件：dealFloat.py
#日期：2019-08-01
#备注：python使用浮点类型float计算后，数值可能不对,这时候需要使用decimal模块
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

from decimal import Decimal,getcontext
from decimal import ROUND_UP,ROUND_DOWN,ROUND_HALF_UP,ROUND_HALF_DOWN,ROUND_HALF_EVEN,ROUND_05UP,ROUND_CEILING ,ROUND_FLOOR

x = 4.20
y = 2.10
a = 1.20
b = 2.30
d = 195.00


def float_info():
    # a.bcd ,精确2位小数点
    i = 1.115  # 在计算机中实际上是1.1149999999999999911182      四舍五入：1.11
    j = 0.125  # d后面没有数据，且c为偶数，那么不进位，保留c        四舍五入：0.12
    l = 0.1251 # d后面有数据，c变成(c + 1)                       四舍五入：0.13
    k = 0.375  # d后面没有数据，且c为奇数，那么进位，c变成(c + 1)   四舍五入：0.38

    print('四舍五入：',round(i,2))
    print('四舍五入：',round(j, 2))
    print('四舍五入：',round(l, 2))
    print('四舍五入：',round(k, 2))


def decimal_info():
    # a.bcd ,精确2位小数点 默认进位方式
    i = 1.115  # 在计算机中实际上是1.1149999999999999911182      四舍五入：1.11
    j = 0.125  # d后面没有数据，且c为偶数，那么不进位，保留c        四舍五入：0.12
    l = 0.1251 # d后面有数据，c变成(c + 1)                       四舍五入：0.13
    k = 0.375  # d后面没有数据，且c为奇数，那么进位，c变成(c + 1)   四舍五入：0.38

    print('浮点型数据不精确：',Decimal(i))
    print('浮点型数据也可能精确：', Decimal(j))
    print('传入的是字符串默认方式四舍五入：', Decimal(str(i)).quantize(Decimal('0.00')))   # 1.12
    print('传入的是浮点型默认方式四舍五入：',Decimal(i).quantize(Decimal('0.00')))         # 1.11
    print('传入的是浮点型默认方式四舍五入：',Decimal(j).quantize(Decimal('0.00')))
    print('传入的是浮点型默认方式四舍五入：',Decimal(l).quantize(Decimal('0.00')))
    print('传入的是浮点型默认方式四舍五入：',Decimal(k).quantize(Decimal('0.00')))
    # 最好传入字符串
    print('传入的是字符串真实四舍五入：', Decimal(str(i)).quantize(Decimal('0.00'), ROUND_HALF_UP))
    print('传入的是字符串真实四舍五入：', Decimal(str(j)).quantize(Decimal('0.00'), ROUND_HALF_UP))
    print('传入的是字符串真实四舍五入：', Decimal(str(l)).quantize(Decimal('0.00'), ROUND_HALF_UP))
    print('传入的是字符串真实四舍五入：', Decimal(str(k)).quantize(Decimal('0.00'),ROUND_HALF_UP))

    print('传入的是字符串向上取值：', Decimal('0.121').quantize(Decimal('0.00'), ROUND_UP))              # 向上入 0.13
    print('传入的是字符串向下取值：', Decimal('0.129').quantize(Decimal('0.00'), ROUND_DOWN))            # 向下舍 0.12
    print('传入的是字符串向上四舍五入：', Decimal('0.125').quantize(Decimal('0.00'), ROUND_HALF_UP))      # 最后一位5向上入 0.13
    print('传入的是字符串向下四舍五入：', Decimal('0.125').quantize(Decimal('0.00'), ROUND_HALF_DOWN))    # 最后一位5向下舍 0.12
    print('传入的是字符串默认方式四舍五入：', Decimal('0.125').quantize(Decimal('0.00'), ROUND_HALF_EVEN))  # 默认四舍五入方式 0.12     quansize的默认设置值
    print('传入的是字符串默认方式四舍五入：', Decimal('0.375').quantize(Decimal('0.00'), ROUND_HALF_EVEN))    # 默认四舍五入方式 0.38
    print('传入的是字符串精确位数字为5入：', Decimal('5.351').quantize(Decimal('0.00'), ROUND_05UP))       # 精确的最后一位为0或者5向上入，否者向下舍5.36
    print('传入的是字符串精确位数字为0入：', Decimal('5.301').quantize(Decimal('0.00'), ROUND_05UP))       # 精确的最后一位为0或者5向上入，否者向下舍5.31
    print('传入的是字符串精确位数字非0和5舍：', Decimal('5.399').quantize(Decimal('0.00'), ROUND_05UP))       # 精确的最后一位为0或者5向上入，否者向下舍5.39
    print('传入的是字符串正数时与ROUND_UP一致：', Decimal('5.391').quantize(Decimal('0.00'), ROUND_CEILING))     # 5.40
    print('传入的是字符串正数时与ROUND_DOWN一致：', Decimal('5.399').quantize(Decimal('0.00'), ROUND_FLOOR))     # 5.39
    print('传入的是字符串负数时与ROUND_DOWN一致：', Decimal('-5.399').quantize(Decimal('0.00'), ROUND_CEILING))    # -5.39  趋近于正无穷
    print('传入的是字符串负数时与ROUND_UP一致：', Decimal('-5.399').quantize(Decimal('0.00'), ROUND_FLOOR))       # -5.40  趋近于负无穷
    print('传入的是字符串与正负无关，最后一位始终进：', Decimal('-5.399').quantize(Decimal('0.00'), ROUND_UP))


def float_deal1():
    z = x + y                     # 6.300000000000001
    print(z)
    if z == 6.30:
        print("z计算正确")
    else:
        print("z计算错误")

    c = a + b
    print(c)
    if c == 3.5:
        print("c计算正确")
    else:
        print("c计算错误")

    e = round(195.00 / 24,2)
    print(e)
    if e == 8.13:
        print("e四舍五入正确")
    else:
        print("e四舍五入错误")


def decimal_deal():
    getcontext().prec = 3                     # 设置精确值,只针对计算时
    z = Decimal(str(x)) + Decimal(str(y))
    print(type(z),z)
    e = Decimal('195.00') / Decimal('24')
    print(e)


# 传入字符串金额得到2尾数的四舍五入金额 （0~4舍，5~9入）
def float_deal(f):
    data = Decimal(str(f)).quantize(Decimal('0.00'),ROUND_HALF_UP)
    #print(data)
    return data


if __name__ == '__main__':
    float_info()
    decimal_info()
    float_deal('1.005')
    decimal_deal()